/***********************************************************************************************************************
* Copyright (C) . All rights reserved.
***********************************************************************************************************************/

/***********************************************************************************************************************
* File Name    : lcd.c
* Version      :  
* Device(s)    : BAT32G137
* Tool-Chain   : MDK(armcc)
* Description  : lcd driver function.
* Creation Date: 2019/12/01
***********************************************************************************************************************/

/***********************************************************************************************************************
Macro Definitions
***********************************************************************************************************************/

/***********************************************************************************************************************
Includes
***********************************************************************************************************************/

#include <stdio.h>
#include "BAT32G157.h"
#include "dma.h"
#include "lcdb.h"
#include "spi.h"

#include "lcd.h"
#include "spi_flash.h"

uint16_t spi_dma_dummy;
//extern volatile uint32_t int_lcdb_flag;
extern volatile uint16_t backcolor;
extern volatile uint32_t lcdbint_cnt;
extern volatile uint32_t spihs1dmacount;

//=======================================================================================================================
void DelayUS(uint32_t us)
{
	while(--us);
}

#if 0
void LCD_WR_REG(uint8_t reg)
{
	LCD_CS_LOW();
	LCD_DC_LOW();
//	DelayUS(48);
	SPI00_MasterSend(reg);
//	DelayUS(48);
	LCD_CS_HIGH();
}

void LCD_WR_DATA(uint8_t dat)
{
	LCD_CS_LOW();
	LCD_DC_HIGH();
//	DelayUS(48);
	SPI00_MasterSend(dat);
//	DelayUS(48);
	LCD_CS_HIGH();
}
#else
void LCD_WR_REG(uint8_t reg)
{
	LCD_CS_LOW();
	LCD_DC_LOW();
	
	Write_LBDATAL(reg);

	LCD_CS_HIGH();
}

void LCD_WR_DATA(uint8_t dat)
{
	LCD_CS_LOW();
	LCD_DC_HIGH();
	
	Write_LBDATAL(dat);

	LCD_CS_HIGH();
}
#endif

#if 0
void LCD_Init(void)
{
	LCD_CS_LOW();	
	LCD_RST_LOW();//HAL_GPIO_WritePin(TFT_RST_GPIO_PortPin,GPIO_PIN_RESET);	
	DelayUS(120*48);//HAL_Delay(120);
	LCD_RST_HIGH();//HAL_GPIO_WritePin(TFT_RST_GPIO_PortPin,GPIO_PIN_SET);
	DelayUS(100*48);//HAL_Delay(10);	
	
	//************* Start Initial Sequence **********// 
LCD_WR_REG(0x36); 
LCD_WR_DATA(0x00);

LCD_WR_REG(0x3A); 
LCD_WR_DATA(0x05);

LCD_WR_REG(0xB2);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x33);
LCD_WR_DATA(0x33); 

LCD_WR_REG(0xB7); 
LCD_WR_DATA(0x35);  

LCD_WR_REG(0xBB);
LCD_WR_DATA(0x19);

LCD_WR_REG(0xC0);
LCD_WR_DATA(0x2C);

LCD_WR_REG(0xC2);
LCD_WR_DATA(0x01);

LCD_WR_REG(0xC3);
LCD_WR_DATA(0x12);   

LCD_WR_REG(0xC4);
LCD_WR_DATA(0x20);  

LCD_WR_REG(0xC6); 
LCD_WR_DATA(0x0F);    

LCD_WR_REG(0xD0); 
LCD_WR_DATA(0xA4);
LCD_WR_DATA(0xA1);

LCD_WR_REG(0xE0);
LCD_WR_DATA(0xD0);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x11);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x2B);
LCD_WR_DATA(0x3F);
LCD_WR_DATA(0x54);
LCD_WR_DATA(0x4C);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x0B);
LCD_WR_DATA(0x1F);
LCD_WR_DATA(0x23);

LCD_WR_REG(0xE1);
LCD_WR_DATA(0xD0);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x11);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x3F);
LCD_WR_DATA(0x44);
LCD_WR_DATA(0x51);
LCD_WR_DATA(0x2F);
LCD_WR_DATA(0x1F);
LCD_WR_DATA(0x1F);
LCD_WR_DATA(0x20);
LCD_WR_DATA(0x23);

LCD_WR_REG(0x21); 

LCD_WR_REG(0x11); 
//Delay (120); 

LCD_WR_REG(0x29); 
	
	//DelayUS(48);
	//LCD_CS_HIGH();
	
	//ShowImage(0);
	
	BACKLIGHT_ON();
	
//	DelayUS(100*48);//HAL_Delay(10);	
	
	Clear_Display(0xf800);//(0x07e0);//(0x001f);
}
#else

void LCD_Init(void)
{
	LCD_CS_LOW();	
	LCD_RST_LOW();//HAL_GPIO_WritePin(TFT_RST_GPIO_PortPin,GPIO_PIN_RESET);	
	DelayUS(120000*48);//HAL_Delay(120);
	LCD_RST_HIGH();//HAL_GPIO_WritePin(TFT_RST_GPIO_PortPin,GPIO_PIN_SET);
	DelayUS(100000*48);//HAL_Delay(10);	
	 
	//************* Start Initial Sequence **********//		
	LCD_WR_REG(0xCF);  
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0xC1); 
	LCD_WR_DATA(0X30); 
	LCD_WR_REG(0xED);  
	LCD_WR_DATA(0x64); 
	LCD_WR_DATA(0x03); 
	LCD_WR_DATA(0X12); 
	LCD_WR_DATA(0X81); 
	LCD_WR_REG(0xE8);  
	LCD_WR_DATA(0x85); 
	LCD_WR_DATA(0x10); 
	LCD_WR_DATA(0x7A); 
	LCD_WR_REG(0xCB);  
	LCD_WR_DATA(0x39); 
	LCD_WR_DATA(0x2C); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x34); 
	LCD_WR_DATA(0x02); 
	LCD_WR_REG(0xF7);  
	LCD_WR_DATA(0x20); 
	LCD_WR_REG(0xEA);  
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x00); 
	LCD_WR_REG(0xC0);    //Power control 
	LCD_WR_DATA(0x1B);   //VRH[5:0] 
	LCD_WR_REG(0xC1);    //Power control 
	LCD_WR_DATA(0x01);   //SAP[2:0];BT[3:0] 
	LCD_WR_REG(0xC5);    //VCM control 
	LCD_WR_DATA(0x30); 	 //3F
	LCD_WR_DATA(0x30); 	 //3C
	LCD_WR_REG(0xC7);    //VCM control2 
	LCD_WR_DATA(0XB7); 
	LCD_WR_REG(0x36);    // Memory Access Control 
	LCD_WR_DATA(0x6C);//(0xC9); 
	LCD_WR_REG(0x3A);   
	LCD_WR_DATA(0x55); 
	LCD_WR_REG(0xB1);   
	LCD_WR_DATA(0x00);   
	LCD_WR_DATA(0x1A); 
	LCD_WR_REG(0xB6);    // Display Function Control 
	LCD_WR_DATA(0x0A); 
	LCD_WR_DATA(0xA2);

	LCD_WR_REG(0xF2);    // 3Gamma Function Disable 
	LCD_WR_DATA(0x00); 
	LCD_WR_REG(0x26);    //Gamma curve selected 
	LCD_WR_DATA(0x01); 
	LCD_WR_REG(0xE0);    //Set Gamma 
	LCD_WR_DATA(0x0F); 
	LCD_WR_DATA(0x2A); 
	LCD_WR_DATA(0x28); 
	LCD_WR_DATA(0x08); 
	LCD_WR_DATA(0x0E); 
	LCD_WR_DATA(0x08); 
	LCD_WR_DATA(0x54); 
	LCD_WR_DATA(0XA9); 
	LCD_WR_DATA(0x43); 
	LCD_WR_DATA(0x0A); 
	LCD_WR_DATA(0x0F); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x00); 		 
	LCD_WR_REG(0XE1);    //Set Gamma 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x15); 
	LCD_WR_DATA(0x17); 
	LCD_WR_DATA(0x07); 
	LCD_WR_DATA(0x11); 
	LCD_WR_DATA(0x06); 
	LCD_WR_DATA(0x2B); 
	LCD_WR_DATA(0x56); 
	LCD_WR_DATA(0x3C); 
	LCD_WR_DATA(0x05); 
	LCD_WR_DATA(0x10); 
	LCD_WR_DATA(0x0F); 
	LCD_WR_DATA(0x3F); 
	LCD_WR_DATA(0x3F); 
	LCD_WR_DATA(0x0F); 
	LCD_WR_REG(0x2B); 
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x01);
	LCD_WR_DATA(0x3f);
	LCD_WR_REG(0x2A); 
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0xef);	 
	LCD_WR_REG(0x11); //Exit Sleep
	DelayUS(120000*48);//delay_ms(120);
	LCD_WR_REG(0x29); //display on
	
	//DelayUS(48);
	//LCD_CS_HIGH();
	
	//ShowImage(0);
	
	BACKLIGHT_ON();
	
//	DelayUS(100*48);//HAL_Delay(10);	
	
	Clear_Display(0x07e0);//(0x001f);//(0xf800);//
}

#endif

void Set_Position(uint16_t x1,uint16_t x2,uint16_t y1,uint16_t y2)
{
	uint16_t xoffset1,xoffset2;
	uint16_t yoffset1,yoffset2;
	
	xoffset1 = TFT_X_OFFSET+x1;
	xoffset2 = TFT_X_OFFSET+x2;
	yoffset1 = TFT_Y_OFFSET+y1;
	yoffset2 = TFT_Y_OFFSET+y2;
	
	//LCD_CS_LOW();
	//DelayUS(48);
	LCD_WR_REG(0x2A);
	LCD_WR_DATA(xoffset1>>8);
	LCD_WR_DATA(xoffset1&0xff);
	LCD_WR_DATA(xoffset2>>8);
	LCD_WR_DATA(xoffset2&0xff);
	LCD_WR_REG(0x2B);
	LCD_WR_DATA(yoffset1>>8);
	LCD_WR_DATA(yoffset1&0xff);
	LCD_WR_DATA(yoffset2>>8);
	LCD_WR_DATA(yoffset2&0xff);
	//DelayUS(48);
	//LCD_CS_HIGH();
//	LCD_WR_REG(0x2C);
//	DelayUS(48);
}

#if 0
void Set_BackColor(uint16_t color)
{
	uint32_t i,j;
	
//	__disable_irq();
	LCD_CS_LOW();

	LCD_DC_LOW();

	//LCD_WR_LOW();

	//PORT->P2 = 0x2C;
	//SPI00_MasterSend(0x2C);
//	DelayUS(48);
	//LCD_WR_HIGH();
	Write_LBDATAL(0x2C);
	
	 LCD_DC_HIGH();
   for(i=0;i<LCD_W*LCD_H;i++)
	 {
//			for (j=0;j<LCD_H;j++)
	   	{
				//LCD_WR_LOW();
			
				//PORT->P2 = color>>8;
				//SPI00_MasterSend(color>>8);
//				DelayUS(48);
				//LCD_WR_HIGH();
//				DelayUS(48);
				//LCD_WR_LOW();
//				DelayUS(48);
				//PORT->P2 = color;
				//SPI00_MasterSend(color);
//				DelayUS(48);
				//LCD_WR_HIGH();
			
//				Write_LBDATAL(color>>8);
//				Write_LBDATAL(color);
				Write_LBDATA(color);
						
	    }

	  }
		
//		DelayUS(48);
		LCD_CS_HIGH();
//		__enable_irq();
}

#else
void Set_BackColor(uint16_t color)
{
	backcolor = color;
	
	LCD_CS_LOW();

	LCD_DC_LOW();

	Write_LBDATAL(0x2C);
	
	LCD_DC_HIGH();
	
//	Write_LBDATAL(color>>8);
//	Write_LBDATAL(color);
	
	//DMA_Start(DMA_VECTOR_LCDB, DMA_CTRL_DATA_LCDB, DMA_MODE_NORMAL, DMA_SIZE_HALF, LCD_W*LCD_H, (uint16_t*)&color, (uint16_t*)&LCDB->LBDATA);
	
	DMAVEC->VEC[DMA_VECTOR_LCDB] = DMA_CTRL_DATA_LCDB;
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMACR = (DMA_SIZE_HALF << CTRL_DMACR_SZ_Pos)      | (1 << CTRL_DMACR_RPTINT_Pos)    |
                                        (0 << CTRL_DMACR_DAMOD_Pos)  | (0 << CTRL_DMACR_SAMOD_Pos) |
                                        (0 << CTRL_DMACR_RPTSEL_Pos)| (DMA_MODE_NORMAL << CTRL_DMACR_MODE_Pos);
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMBLS = 1;
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMACT = (LCD_W*LCD_H)/2-1;
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMRLD = (LCD_W*LCD_H)/2-1;
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMSAR = (uint32_t)((uint16_t*)&backcolor);
    DMAVEC->CTRL[DMA_CTRL_DATA_LCDB].DMDAR = (uint32_t)((uint16_t*)&LCDB->LBDATA);

    /* init DMA registers */
    CGC->PER1   |= CGC_PER1_DMAEN_Msk;
    DMA->DMABAR  = DMAVEC_BASE;
    
	DMA_Enable(DMA_VECTOR_LCDB);
	LCDB_Start();
	
	lcdbint_cnt = 0;

	LCDB->LBDATA = color;
	
//	int_lcdb_flag = 0;
//	while(!int_lcdb_flag);
	
//	DelayUS(48);
//	LCD_CS_HIGH();
//	
//	LCDB_Stop();
	
}
#endif

void Clear_Display(uint16_t color)
{
	Set_Position(0,LCD_W-1,0,LCD_H-1);
	Set_BackColor(color);
}


void Delayns(uint32_t ns)
{
	while(--ns);
}

void ShowImage(uint8_t imagenum)
{
	uint16_t  dummy;
	
	uint32_t addr = SPI_FLASH_ADDR+LCD_W*LCD_H*2*imagenum;//SPI_FLASH_ADDR+0x20000*imagenum;
	
	//SPI->SPIM = _0080_SPI_START_TRG_ON | _0040_SPI_RECEPTION_TRANSMISSION | _0000_SPI_MSB | _0000_SPI_LENGTH_8;
	
	Set_Position(0,LCD_W-1,0,LCD_H-1);
	
//	SPIHS1->SPIM1 &= ~_0010_SPI_LSB;
	SPIHS1->SPIM1 &= ~_0004_SPI_LENGTH_16;
	SPIHS1->SPIM1 &= ~_0002_SPI_CONTINOUS_RECEPTION;
	SPIHS1->SPIM1 |= _0040_SPI_RECEPTION_TRANSMISSION;
	
	 /* /CS: active */
    SPI_CS_LOW();

    /* Send command 0x0B: Read data */
    SPIHS1_Send(0x0B);
    /* Send 24-bit start address */
    SPIHS1_Send( (addr >> 16) & 0xFF);
    SPIHS1_Send( (addr >> 8) & 0xFF);
    SPIHS1_Send(addr & 0xFF);
    SPIHS1_Send(0xff);//dummy
	
	LCD_CS_LOW();

	LCD_DC_LOW();

	Write_LBDATAL(0x2C);
	
	LCD_DC_HIGH();
	
//	SPIHS1->SPIM1 |= _0010_SPI_LSB;
	SPIHS1->SPIM1 |= _0004_SPI_LENGTH_16;
//	SPIHS1->SPIM1 |= _0002_SPI_CONTINOUS_RECEPTION;
	SPIHS1->SPIM1 &= ~_0040_SPI_RECEPTION_TRANSMISSION;
	
    DMAVEC->VEC[DMA_VECTOR_SPIHS1] = SPI_DMA_CHANNEL;
    
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMACR = (DMA_SIZE_HALF << CTRL_DMACR_SZ_Pos)  | (0<<CTRL_DMACR_CHNE_Pos) | (0 << CTRL_DMACR_RPTINT_Pos) |
                                        (0 << CTRL_DMACR_DAMOD_Pos)  | (0 << CTRL_DMACR_SAMOD_Pos) |
                                        (0 << CTRL_DMACR_RPTSEL_Pos)| (DMA_MODE_NORMAL << CTRL_DMACR_MODE_Pos);
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMBLS = 1;
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMACT = (LCD_W*LCD_H)/2;
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMRLD = (LCD_W*LCD_H)/2;
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMSAR = (uint32_t)(&SPIHS1->SDRI1);
    DMAVEC->CTRL[SPI_DMA_CHANNEL].DMDAR = (uint32_t)((uint16_t*)&LCDB->LBDATA);
	
//	DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMACR = (DMA_SIZE_HALF << CTRL_DMACR_SZ_Pos)  | (0<<CTRL_DMACR_CHNE_Pos) | (0 << CTRL_DMACR_RPTINT_Pos) |
//                                        (0 << CTRL_DMACR_DAMOD_Pos)  | (0 << CTRL_DMACR_SAMOD_Pos) |
//                                        (0 << CTRL_DMACR_RPTSEL_Pos)| (DMA_MODE_NORMAL << CTRL_DMACR_MODE_Pos);
//    DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMBLS = 1;
//    DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMACT = (LCD_W*LCD_H)/2;
//    DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMRLD = (LCD_W*LCD_H)/2;
//    DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMSAR = (uint32_t)&spi_dma_dummy;
//    DMAVEC->CTRL[SPI_DMA_CHANNEL+1].DMDAR = (uint32_t)(&SPIHS1->SDRO1);
	
    /* init DMA registers */
    CGC->PER1   |= CGC_PER1_DMAEN_Msk;
    DMA->DMABAR  = DMAVEC_BASE;
	DMA_Enable(DMA_VECTOR_SPIHS1);
	spihs1dmacount = 0;//block 0
	
	//SPI->SPIM = _0080_SPI_START_TRG_ON | _0000_SPI_MSB | _0000_SPI_LENGTH_8 ;//| _0008_SPI_BUFFER_EMPTY;//_0040_SPI_RECEPTION_TRANSMISSION | 
	dummy = SPIHS1->SDRI1;
//	SPIHS1->SDRO1 = 0xffff;
	
	INTC_ClearPendingIRQ(SPI1_IRQn);
	INTC_EnableIRQ(SPI1_IRQn);
//	DMA->IFPRCR  = 0xF1U;
//	DMA->DMAIF2  |= 1<<(DMA_VECTOR_SPIHS1%8);//DMA_Trigger(DMA_VECTOR_SPIHS1);
	
}

